package {{packageName}}.util.domain;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.flowable.bpmn.model.Process;
import org.kie.api.runtime.KieContainer;
import org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint;
import org.springframework.core.io.Resource;
import org.apache.commons.logging.Log;
import java.util.List;
import org.springframework.util.ObjectUtils;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;

@Getter
@Setter
@NoArgsConstructor
@Accessors(chain = true)
public class DELogic{
    String id;
    String name;
    Process process;
    KieContainer container;
    String md5;
    int logicMode;
    long loadedTime;
    Map<String,DELogic> refLogicMap;
    Map<String,Resource> refRuleFilesMap;
    Map<String,Process> refProcessMap;

    public Collection<DELogic> getRefLogic() {
        return refLogicMap != null? refLogicMap.values() : null;
    }

    public Collection<Resource> getRefRuleFiles() {
        return refRuleFilesMap != null ? refRuleFilesMap.values() : null;
    }

    public Map<String, Process> getRefProcessMap() {
        if(refProcessMap == null){
            refProcessMap = new LinkedHashMap<>();
            if(!ObjectUtils.isEmpty(getRefLogic())){
                for(DELogic deLogic : getRefLogic()){
                    if(deLogic.getProcess() != null){
                        refProcessMap.put(deLogic.getProcess().getId(),deLogic.getProcess());
                    }
                }
            }
        }
        return refProcessMap;
    }

    @Getter
    @Setter
    @NoArgsConstructor
    @Accessors(chain = true)
    public static class LoopNode{
        /**
         * 节点标识
         */
        String nodeId;
        /**
         * 节点名称
         */
        String nodeName;
        /**
         * 循环体
         */
        List loopBody;
        /**
         * 循环次数
         */
        int loopCount;
        /**
         * 当前次数
         */
        int loopCurrent;
        /**
         * 循环状态
         */
        boolean active;

        /**
         * 循环节点初始化
         * @param loopBody
         */
        public void init(List loopBody){
            this.setLoopBody(loopBody);
            this.setLoopCurrent(0);
            this.setLoopCount(!ObjectUtils.isEmpty(loopBody)? loopBody.size() : 0);
            this.setActive(true);
        }

        /**
         * 循环节点完成
         */
        public void done(){
            this.setLoopBody(null);
            this.setLoopCurrent(0);
            this.setLoopCount(0);
            this.setActive(false);
        }
    }

    @Getter
    @Setter
    @NoArgsConstructor
    @Accessors(chain = true)
    public static class Context{
        JoinPoint point;
        Log log;
        Object pointValue;
        DELogic logic;
        Object logicReturnValue;
    }

    @Getter
    @Setter
    @NoArgsConstructor
    @Accessors(chain = true)
    public static class Param{
        String type;
        String express;
        String name;

        public boolean isEntity(){
            return "entity".equalsIgnoreCase(type);
        }
    }


    public static class JoinPoint{
        private MethodInvocationProceedingJoinPoint point;
        public JoinPoint(MethodInvocationProceedingJoinPoint point){
            this.point = point;
        }
        public Object proceed(){
            Object result ;
            try{
                result = point.proceed();
            }
            catch(Throwable e){
                e.printStackTrace();
                throw new RuntimeException("执行行为发生异常:"+e.getMessage());
            }
            return result;
        }
    }
}